import 'package:ceramics/cache.dart';
import 'package:ceramics/extensions/ab_list_extensions.dart';
import 'package:ceramics/extensions/ab_widget_extensions.dart';
import 'package:ceramics/model/ab_comment.dart';
import 'package:ceramics/model/ab_like.dart';
import 'package:ceramics/model/ab_singleton.dart';
import 'package:ceramics/model/ab_video.dart';
import 'package:ceramics/pages/main/ab_main_tab_page.dart';
import 'package:ceramics/pages/main/video/ab_comment_sheet.dart';
import 'package:ceramics/pages/main/video/ab_video_item.dart';
import 'package:ceramics/styles/ab_styles.dart';
import 'package:ceramics/util/ab_api.dart';
import 'package:ceramics/util/ab_init_db.dart';
import 'package:ceramics/widgets/ab_elevate_button.dart';
import 'package:ceramics/widgets/ab_image.dart';
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
import 'package:get/get.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'package:video_player/video_player.dart';

class ABVideoHomePageController extends GetxController {
  static ABVideoHomePageController get to =>
      Get.find<ABVideoHomePageController>();
  var videos = <ABVideo>[].obs;
  var swipeController = SwiperController();
  VideoPlayerController? videoPlayerController;
  Rxn<ChewieController> chewieController = Rxn<ChewieController>();
  var ratio = 16.0 / 9.0;
  var currentIndex = 0.obs;
  var isPlaying = false.obs;
  var isBuffering = false.obs;
  var position = 0.0.obs;
  var currentVideoId = 0.obs;
  Worker? debounceWorker;
  var dLike = true.obs;
  ABVideo? handleModel;
  var textController = TextEditingController();

  var comments = <ABComment>[].obs;

  @override
  void onInit() {
    super.onInit();
    _fetchAllFollowsAndVideos();
    _initDebounce();
  }

  _fetchAllFollowsAndVideos() async {
    await ABSingleton.updateFollows();
    initAllVideos();
  }

  _initDebounce() {
    debounceWorker = debounce(dLike, (callback) async {
      var model = handleModel!;
      var likeId = 'video_${model.id}';
      var isLike = model.isLiked.value;
      if (isLike) {
        if (ABSingleton.likes.any((element) => element.likeId == likeId)) {
          return;
        }
        await ABLike.insertLike(likeId);
        ABSingleton.likes.value = await ABLike.queryAllLikes();
        await model.save();
      } else {
        await ABLike.deleteLike(likeId);
        ABSingleton.likes.value = await ABLike.queryAllLikes();
        await model.save();
      }
    });
  }

  Future<void> initAllVideos() async {
    await queryVideos();
    if (videos.isNotEmpty) {
      var tabIndex = Get.find<ABMainTabController>().tabIndex.value;
      if (tabIndex == 1) {
        if (currentIndex.value < videos.length) {
          _changeVideo(currentIndex.value, false);
        } else {
          _changeVideo(0, false);
        }
      } else {
        _changeVideo(0, false);
      }
    }
    update();
  }

  _changeVideo(int idx, bool play) async {
    currentIndex.value = idx;
    currentVideoId.value = videos[idx].id;
    position.value = 0.0;
    var url = videos[idx].videoOss?.mediaUrl ?? "";
    if (url.isEmpty) {
      var res = await api.fetchOssURL([OSSRequest(videos[idx].video!, 'image')]);
      url = res.first.mediaUrl;
    }
    var localURL = await ktvChannel.invokeMethod('localURL',{'url':url});
    await videoPlayerController?.pause();
    videoPlayerController = VideoPlayerController.networkUrl(Uri.parse(url));
    await videoPlayerController!.initialize();
    videoPlayerController?.addListener(_videoListener);
    chewieController.value = ChewieController(
        videoPlayerController: videoPlayerController!,
        customControls: const CupertinoControls(
          backgroundColor: Colors.red,
          iconColor: Colors.white,
        ),
        showControls: false,
        allowMuting: false,
        allowPlaybackSpeedChanging: false);
    if (play) {
      videoPlayerController?.play();
    }
  }

  _videoListener() {
    isPlaying.value = videoPlayerController!.value.isPlaying;
    isBuffering.value = videoPlayerController!.value.isBuffering;
    position.value =
        videoPlayerController!.value.position.inMilliseconds.toDouble();
  }

  queryVideos() async {
    videos.value = await ABVideo.queryVideos();
  }

  void showCommentSheet() {
    showMaterialModalBottomSheet(
        context: Get.context!,
        builder: (ctx) {
          return ABCommentSheet(videoId: videos[currentIndex.value].id, textController: textController);
        },
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
        ),
        duration: const Duration(milliseconds: 200),
        backgroundColor: Colors.transparent);
  }

  void toggleFollow(String userId) async {
    if (ABSingleton.didFollow(userId)) {
      await api.unfollow(userId);
      ABSingleton.follows
          .removeWhere((element) => element.userId == userId);
    } else {
      await api.follow(userId);
      await ABSingleton.updateFollows();
    }
    update();
  }
}

class ABVideoHomePage extends GetView<ABVideoHomePageController> {
  const ABVideoHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      resizeToAvoidBottomInset: false,
      body: GetBuilder<ABVideoHomePageController>(
        assignId: true,
        builder: (logic) {
          return SafeArea(
            top: false,
            bottom: false,
            child: Obx(() {
              return Swiper(
                  itemCount: controller.videos.length,
                  onIndexChanged: (idx) {
                    print(idx);
                    controller._changeVideo(idx, true);
                  },
                  loop: false,
                  onTap: (idx) {
                    if (controller.isPlaying.value) {
                      controller.videoPlayerController?.pause();
                    } else {
                      controller.videoPlayerController?.play();
                    }
                  },
                  itemBuilder: (context, index) {
                    return _buildPageItem(index);
                  },
                  controller: controller.swipeController,
                  scrollDirection: Axis.vertical);
            }),
          );
        },
      ),
    );
  }

  Widget _buildPageItem(int index) {
    var model = controller.videos[index];
    return ABVideoItem(model: model,index: index);
  }
}
